import sys
import traceback
import types

from PyQt5 import QtWidgets, QtCore

from .mainwindow import MainWindow


def excepthook(exctype: type, value: Exception, tb: types.TracebackType) -> None:
    """
    Raise exception under debug mode, otherwise
    show exception detail with QMessageBox.
    """
    sys.__excepthook__(exctype, value, tb)

    msg = "".join(traceback.format_exception(exctype, value, tb))
    dialog = ExceptionDialog(msg)
    dialog.signal.emit()


def create_qapp() -> QtWidgets.QApplication:
    """
    创建一个应用程序对象
    """
    sys.excepthook = excepthook

    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    qapp = QtWidgets.QApplication(sys.argv)

    return qapp


class ExceptionDialog(QtWidgets.QDialog):
    """"""
    signal = QtCore.pyqtSignal()

    def __init__(self, msg: str):
        """"""
        super().__init__()

        self.msg: str = msg

        self.init_ui()
        self.signal.connect(self.exec_)

    def init_ui(self) -> None:
        """"""
        self.setWindowTitle("触发异常")
        self.setFixedSize(600, 600)

        self.msg_edit = QtWidgets.QTextEdit()
        self.msg_edit.setText(self.msg)
        self.msg_edit.setReadOnly(True)

        copy_button = QtWidgets.QPushButton("复制")
        copy_button.clicked.connect(self._copy_text)

        close_button = QtWidgets.QPushButton("关闭")
        close_button.clicked.connect(self.close)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addWidget(copy_button)
        hbox.addWidget(close_button)

        vbox = QtWidgets.QVBoxLayout()
        vbox.addWidget(self.msg_edit)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def _copy_text(self) -> None:
        """"""
        self.msg_edit.selectAll()
        self.msg_edit.copy()
